package
{
	import flash.display.Sprite;
	import flash.display.Stage3D;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DRenderMode;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.Program3D;
	import flash.display3D.VertexBuffer3D;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.Endian;

	public class FileData extends Sprite
	{
		private var _stage3d:Stage3D;

		private var _context3d:Context3D;

		private var files:Array = ["ver.stage3dvertex", "ver.stage3dindex", "ver.stage3dvagal", "ver.stage3dfagal"];

		private var filesIndex:uint = 0;

		private var bytes:Array = [];

		private var _vb:VertexBuffer3D;

		private var _ib:IndexBuffer3D;

		private var _pm:Program3D;

		private var vdr:VertexDataRead = new VertexDataRead();

		private var idr:IndexDataRead = new IndexDataRead();

		private var vagal:ByteArray;

		private var fagal:ByteArray;

		public function FileData()
		{
			trace("stage3D层数量：", stage.stage3Ds.length);
			if (stage.stage3Ds.length > 0)
			{
				this._stage3d = stage.stage3Ds[0];
				this._stage3d.addEventListener(Event.CONTEXT3D_CREATE, created_handler);
				this._stage3d.addEventListener(ErrorEvent.ERROR, created_error_handler);
				this._stage3d.requestContext3D(Context3DRenderMode.AUTO);
			}
		}

		private function created_error_handler(evt:ErrorEvent):void
		{
			trace("GPU启动失败或设备丢失!");
		}

		private function created_handler(evt:Event):void
		{
			trace("GPU设备类型：", this._stage3d.context3D.driverInfo);
			this._context3d = this._stage3d.context3D;
			this._context3d.enableErrorChecking = true;
			this._context3d.configureBackBuffer(300, 300, 0, true);
			this.loadFile(this.files[this.filesIndex]);
		}

		private function loadFile(url:String):void
		{
			var data:URLLoader = new URLLoader();
			data.dataFormat = URLLoaderDataFormat.BINARY;
			data.addEventListener(Event.COMPLETE, dataload_complate_handler);
			data.load(new URLRequest(File.applicationDirectory.resolvePath(url).nativePath));
		}

		private function dataload_complate_handler(evt:Event):void
		{
			var byte:ByteArray = evt.target.data;
			byte.endian = Endian.LITTLE_ENDIAN;
			this.bytes.push(byte);
			this.filesIndex++;
			if (this.filesIndex < this.files.length)
			{
				this.loadFile(this.files[this.filesIndex]);
			}
			else
			{
				updateAll();
			}
		}

		private function updateAll():void
		{
			this.vdr.read(this.bytes[0]);
			this.idr.read(this.bytes[1]);
			this.vagal = this.bytes[2];
			this.fagal = this.bytes[3];
			addTriangle();
			this.addEventListener(Event.ENTER_FRAME, draw);
		}

		private function addTriangle():void
		{
			this._vb = this._context3d.createVertexBuffer(vdr.numVertices, vdr.data32PerVertex);
			this._vb.uploadFromByteArray(vdr.data, 0, 0, vdr.numVertices);
			this._ib = this._context3d.createIndexBuffer(idr.numVertices);
			this._ib.uploadFromByteArray(idr.data, 0, 0, idr.numVertices);
			this._pm = this._context3d.createProgram();
			this._pm.upload(vagal, fagal);
			this._context3d.setVertexBufferAt(0, this._vb, 0, Context3DVertexBufferFormat.FLOAT_2);
			this._context3d.setVertexBufferAt(1, this._vb, 2, Context3DVertexBufferFormat.FLOAT_3);
			this._context3d.setProgram(this._pm);
		}

		private function draw(evt:Event):void
		{
			this._context3d.clear(0, 0, 0);
			this._context3d.drawTriangles(this._ib);
			this._context3d.present();
		}

		private function click_handler(evt:MouseEvent):void
		{
			this._context3d.dispose();
		}
	}
}
